package com.sbillings.messenger.hub;

import java.util.Properties;
import com.sbillings.messenger.hub.Message;
import com.sbillings.messenger.hub.Subscriber;
import com.sbillings.messenger.hub.NotificationStrategy;

// import javax.mail.Message;  // This conflicts, so don't import; use qualified Type instead
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

/**
 * A NotificationStrategy (for use by Subscribers) that sends messages by email.
 * @author steve.billings
 *
 */
public class EmailNotificationStrategy implements NotificationStrategy {
	
    private Session smtpSession;
    private String fromEmail;
	
    /**
     * The constructor takes a Properties object with the following values set:
     * username: SMTP server username
     * password: SMTP server password
     * SMTP configuration (see )
     * mail.smtp.auth
     * mail.smtp.starttls.enable
	 * mail.smtp.host
	 * mail.smtp.port
     * @param notificationStrategyProperties
     */
	public EmailNotificationStrategy(Properties notificationStrategyProperties) {
		final String username = notificationStrategyProperties.getProperty("username", "<not set>");
        final String password = notificationStrategyProperties.getProperty("password", "<not set>");
        fromEmail = username;
        Properties smtpSessionProperties = new Properties();
        smtpSessionProperties.put("mail.smtp.auth", notificationStrategyProperties.getProperty("mail.smtp.auth", "<not set>"));
        smtpSessionProperties.put("mail.smtp.starttls.enable", notificationStrategyProperties.getProperty("mail.smtp.starttls.enable", "<not set>"));
        smtpSessionProperties.put("mail.smtp.host", notificationStrategyProperties.getProperty("mail.smtp.host", "<not set>"));
        smtpSessionProperties.put("mail.smtp.port", notificationStrategyProperties.getProperty("mail.smtp.port", "<not set>"));
		smtpSession = getSmtpSession(username, password, smtpSessionProperties);
	}
	
	/**
	 * Create the SMTP Session object.
	 * @param username SMTP username
	 * @param password SMTP password
	 * @param smtpSessionProperties a properties object with the SMTP configuration set.
	 * @return
	 */
	private Session getSmtpSession(final String username, final String password, Properties smtpSessionProperties) {
		Session smtpSession = Session.getInstance(smtpSessionProperties, new javax.mail.Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(username, password);
            }
        });
		return smtpSession;
	}

	/**
	 * Send the given message to the given subscriber by email.
	 * @param subscriber the subscriber who should receive the message
	 * @param message the message to send
	 */
	public void sendMessage(Subscriber subscriber, Message message) {
		String emailSubject = "Messenger notification: source=" + message.getSource() + 
				", type=" + message.getType().getName();
		this.sendEmail(subscriber.getEmail(), emailSubject, message.getBody());
	}
	
	
	/**
	 * Send email with the given subject and body. 
	 * @param toEmail destination email address
	 * @param subject email subject line
	 * @param body email body
	 */
    public void sendEmail(String toEmail, String subject, String body) {
        try {
            javax.mail.Message emailMessage = new MimeMessage(smtpSession);
            emailMessage.setFrom(new InternetAddress(fromEmail)); // From email
            emailMessage.setRecipients(javax.mail.Message.RecipientType.TO, InternetAddress.parse(toEmail)); // To email
            emailMessage.setSubject(subject);
            emailMessage.setText(body);
            Transport.send(emailMessage);
        } catch (MessagingException e) {
            System.out.println("Error sending email: " + subject + "\n\n" + body + "\n\n" + e.getMessage());
        }

    }
}

